package com.yuandian.customer.perception.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuandian.api.business_monitor.po.SearchParams;
import com.yuandian.api.customer_perception.po.BusinessComplianceStatisticsParms;
import com.yuandian.api.customer_perception.po.StepDetailParams;
import com.yuandian.api.customer_perception.vo.*;
import com.yuandian.api.management.entity.ConfBusiness;
import com.yuandian.api.management.entity.ConfSystem;
import com.yuandian.api.management.feign.RemoteBusinessHallService;
import com.yuandian.api.management.feign.RemoteBusinessService;
import com.yuandian.api.management.feign.RemoteSystemService;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.customer.perception.mapper.BusinessComplianceStatisticsMapper;
import com.yuandian.customer.perception.service.BusinessComplianceStatisticsService;
import com.yuandian.utils.PageDataInfo;
import com.yuandian.utils.poi.ExcelTitleUtils;
import com.yuandian.utils.poi.ExcelUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 业务合规统计 服务类
 *
 * @author LinShiHe
 * @since 2021-05-18
 */
@Slf4j
@Service
public class BusinessComplianceStatisticsServiceImpl implements BusinessComplianceStatisticsService {

	@Autowired
	private BusinessComplianceStatisticsMapper businessMapper;
	@Autowired
	private RemoteSystemService systemService;
	@Autowired
	private RemoteBusinessService businessService;
	@Autowired
	private RemoteBusinessHallService businessHallService;

/*
    @Autowired
    private ISearchOptionService searchOptionService;	TODO 远程调用
*/

	/**
	 * 分页查询操作员总览列表
	 *
	 * @param params
	 * @return 返回分页对象
	 */
	@Override
	public PageDataInfo queryOperatorOverview(BusinessComplianceStatisticsParms params) {
		Page<ComOperatorOverviewVO> page = new Page<>(params.getPageNum(), params.getPageSize());
		//默认排序
		if (StringUtils.isEmpty(params.getOrderByColumn())) {
			params.setOrderByColumn("lastVisitTime");
			params.setIsAsc("desc");
		}
		List<ComOperatorOverviewVO> list = businessMapper.queryOperatorOverview(page, params);
		for (ComOperatorOverviewVO vo : list) {
			if (ObjectUtil.isEmpty(vo.getOperatorId())) {
				vo.setOperatorId(UUID.randomUUID().toString());
			}
			if (ObjectUtil.isEmpty(vo.getOperatorName())) {
				vo.setOperatorName("操作员" + UUID.randomUUID().toString());
			}

			switch (vo.getUnComplianceType()) {
				case 1:
					vo.setUnComplianceTypeStr("操作不完整");
					break;
				case 2:
					vo.setUnComplianceTypeStr("中间步骤失败");
					break;
				case 3:
					vo.setUnComplianceTypeStr("操作频率过高");
					break;
				case 4:
					vo.setUnComplianceTypeStr("非活跃账号异常");
					break;
				case 5:
					vo.setUnComplianceTypeStr("账号归属异常");
					break;
				default:
					vo.setUnComplianceTypeStr("未知异常");
					break;
			}
		}
		list.forEach(one -> {
			if (one.getLastVisitTime() != null && !("").equals(one.getLastVisitTime())) {
				one.setLastVisitTime(one.getLastVisitTime().replace(".0", ""));
			}
			if (one.getFirstVisitTime() != null && !("").equals(one.getFirstVisitTime())) {
				one.setFirstVisitTime(one.getFirstVisitTime().replace(".0", ""));
			}
		});
		return new PageDataInfo(page, list);
	}

	/**
	 * 分页查询XX(工号)操作员(姓名)不合规业务总览列表
	 *
	 * @param params
	 * @return 通用返回对象
	 */
	@Override
	public PageDataInfo queryOneOperatorStatistic(BusinessComplianceStatisticsParms params) {
		//operatorId为空不返回数据
		Page<ComOperatorOverviewVO> page = new Page<>(params.getPageNum(), params.getPageSize());
		if (params.getOperatorId() == null || params.getOperatorId().equals("")) {
			return new PageDataInfo(page);
		}
		//默认排序
		if (StringUtils.isEmpty(params.getOrderByColumn())) {
			params.setOrderByColumn("lastVisitTime");
			params.setIsAsc("desc");
		}
		List<OneOperatorStatisticVO> list = businessMapper.queryOneOperatorStatistic(params);
		for (OneOperatorStatisticVO vo : list) {
			switch (vo.getUnComplianceType()) {
				case 1:
					vo.setUnComplianceTypeStr("操作不完整");
					break;
				case 2:
					vo.setUnComplianceTypeStr("中间步骤失败");
					break;
				case 3:
					vo.setUnComplianceTypeStr("操作频率过高");
					break;
				case 4:
					vo.setUnComplianceTypeStr("非活跃账号异常");
					break;
				case 5:
					vo.setUnComplianceTypeStr("账号归属异常");
					break;
				default:
					vo.setUnComplianceTypeStr("未知异常");
					break;
			}
		}
		list.forEach(one -> {
			if (one.getLastVisitTime() != null && !("").equals(one.getLastVisitTime())) {
				one.setLastVisitTime(one.getLastVisitTime().replace(".0", ""));
			}
			if (one.getFirstVisitTime() != null && !("").equals(one.getFirstVisitTime())) {
				one.setFirstVisitTime(one.getFirstVisitTime().replace(".0", ""));
			}
		});
		return new PageDataInfo(page, list);
	}

	/**
	 * 下载XX(工号)操作员(姓名)不合规业务总览列表
	 *
	 * @param params
	 * @param response
	 * @return 通用返回对象
	 */
	@Override
	public void downloadOneOperatorStatistic(BusinessComplianceStatisticsParms params, HttpServletResponse response) throws IOException {
		//取消分页
		params.setPageNum(1);
		params.setPageSize(-1);
		List<OneOperatorStatisticVO> oneOperatorStatisticVOS = new ArrayList<>();
		try {
			oneOperatorStatisticVOS = (List<OneOperatorStatisticVO>) queryOneOperatorStatistic(params).getData();
		} catch (Exception e) {
			log.error("所选时间表不存在!但表格需要正常导出.");
		}
		int index = 1;
		for (OneOperatorStatisticVO vo : oneOperatorStatisticVOS) {
			vo.setId(index++);
		}
		//excel主标题,如"XX(工号)操作员(姓名)不合规业务总览_startTime~endTime"
		String title = "不合规业务总览";
		List<String> titleParams = new ArrayList<>();
		titleParams.add(title);
		if (params.getSystemId() != null) {
			ConfSystem system = systemService.getSystemById(params.getSystemId()).getData();
			if (ObjectUtil.isNotEmpty(system)) {
				titleParams.add(system.getName());
			}
		}
		if (StringUtils.isNotEmpty(params.getBusinessCode())) {
			ConfBusiness confBusiness = new ConfBusiness();
			confBusiness.setBusinessCode(params.getBusinessCode());
			List<ConfBusiness> data = businessService.getBusiness(confBusiness).getData();
			if (ObjectUtil.isNotEmpty(data) && data.size() > 1) {
				confBusiness = data.get(0);
				titleParams.add(confBusiness.getName());
			}
		}
		titleParams.add(params.getOperatorId());
		titleParams.add(params.getOperatorName());
		String formTitleName = ExcelTitleUtils.formTitleName(titleParams, params.getDownloadStartTime(), params.getDownloadEndTime());
		//列标题
		List<List<String>> headList = new ArrayList<>();
		List<String> titleList = Arrays.asList("序号", "系统名称", "业务名称", "业务不合规类型", "访问量", "最早操作时间", "最近操作时间");
		titleList.forEach(s -> {
			List<String> childHeadList = new ArrayList<>();
			childHeadList.add(formTitleName);
			childHeadList.add(s);
			headList.add(childHeadList);
		});
		ExcelUtil.writeExcel(OneOperatorStatisticVO.class, formTitleName, "不合规业务总览", oneOperatorStatisticVOS, headList, response);
	}

	@Override
	public PageDataInfo queryStepDetailList(StepDetailParams params) {
		Page<StepDetailVo> page = new Page<>(params.getPageNum(), params.getPageSize());
		List<StepDetailVo> list = businessMapper.queryStepDetailList(page, params);
		page.setRecords(list);
		return new PageDataInfo(page);
	}

	/**
	 * 操作员总览列表下载
	 *
	 * @param params
	 * @return 通用返回对象
	 */
	@Override
	public List<ComOperatorOverviewVO> downloadOperatorOverview(BusinessComplianceStatisticsParms params) {
		//取消分页
		params.setPageNum(1);
		params.setPageSize(-1L);
		//默认排序
		if (StringUtils.isEmpty(params.getOrderByColumn())) {
			params.setOrderByColumn("lastVisitTime");
			params.setIsAsc("desc");
		}
		PageDataInfo pageDataInfo = queryOperatorOverview(params);
		List<ComOperatorOverviewVO> list = new ArrayList<>();
		try {
			list = (List<ComOperatorOverviewVO>) pageDataInfo.getData();
		} catch (Exception e) {
			log.error("所选时间表不存在!但表格需要正常导出.");
		}
		list.forEach(businessComplianceStatistics -> {
			if (businessComplianceStatistics.getLastVisitTime() != null && !("").equals(businessComplianceStatistics.getLastVisitTime())) {
				businessComplianceStatistics.setLastVisitTime(businessComplianceStatistics.getLastVisitTime().replace(".0", ""));
			}
			if (businessComplianceStatistics.getFirstVisitTime() != null && !("").equals(businessComplianceStatistics.getFirstVisitTime())) {
				businessComplianceStatistics.setFirstVisitTime(businessComplianceStatistics.getFirstVisitTime().replace(".0", ""));
			}
		});
		return list;
	}

	/**
	 * 根据搜索条件查询各种不合规类型的数据量
	 *
	 * @param params 查询参数（工号、营业员姓名、业务编码、业务不合规类型、统计时间等）
	 * @return 通用返回对象
	 */
	@Override
	public R<Object> queryEchartDataByUnComplianceType(BusinessComplianceStatisticsParms params) {
		BusinessCompliancePercentVo res = new BusinessCompliancePercentVo();
		List<ComOperatorOverviewVO> list = businessMapper.selectEchartDataByUnComplianceType(params);
		res.setTotal(list.size());
		int unComplianceTypeNum = 0;
		int stepFailedNum = 0;
		int highFrequenceNum = 0;
		int noComplianceTotal = 0;
		for (ComOperatorOverviewVO l : list) {
			switch (l.getUnComplianceType()) {
				case 1:
					res.setNotSubmitted(unComplianceTypeNum += l.getCount());
					break;
				case 2:
					res.setStepFailed(stepFailedNum += l.getCount());
					break;
				case 3:
					res.setHighFrequence(highFrequenceNum += l.getCount());
					break;
				default:
					break;
			}
			noComplianceTotal += l.getCount();
		}
		res.setNoComplianceTotal(noComplianceTotal);
		//传递人数
		List<Map<Integer, Integer>> operatorNumbers = businessMapper.queryOperatorNumber(params);
		int[] operatorNumber = {0, 0, 0};
		for (Map<Integer, Integer> map : operatorNumbers) {
			Integer unComplianceType = map.get("unComplianceType");
			String operator = map.get("operatorNumber") + "";
			operatorNumber[unComplianceType - 1] = Integer.parseInt(operator);
		}
		res.setOperatorNumber(operatorNumber);
		return R.ok(res);
	}

	/**
	 * 分页查询XX(工号)操作员(姓名)不合规业务列表
	 *
	 * @param params 查询参数
	 * @return 分页结果集
	 */
	@Override
	public R<PageDataInfo> queryViolationBusinessList(BusinessComplianceStatisticsParms params) {
		//operatorId为空不返回数据
		if (params.getOperatorId() == null || params.getOperatorId().equals("")) {
			return null;
		}
		// 默认排序
		if (StringUtils.isEmpty(params.getOrderByColumn())) {
			params.setOrderByColumn("endTime");
			params.setIsAsc("desc");
		}
		List<BusinessComplianceStatisticsVo> sdVoList = new ArrayList<>();
		List<IsHallErrorVO> ihVoList = new ArrayList<>();


		// 如果是当天的保持数据一致
		long today = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
		if (params.getLastVisitTime() != null && DateUtil.parse(params.getLastVisitTime()).getTime() > today) {
			params.setLastVisitTimeLong(DateUtil.parse(params.getLastVisitTime()).getTime());
		}


		// 2.3、分页查询，返回结果
		Page<BusinessComplianceStatisticsVo> page = new Page<>(params.getPageNum(), params.getPageSize());
		List<BusinessComplianceStatisticsVo> voList = businessMapper.queryViolationBusinessList(page, params);


		// 3、处理结果
		// 查询设定营业厅名称+ID
//        List<String> attributionPlaces = businessMapper.queryAttributionPlace(params.getOperatorId());//
		SearchParams searchParams = new SearchParams();
		searchParams.setOperatorName(params.getOperatorName());
		List<Map<String, String>> hallList = businessHallService.getBusinessHall(searchParams).getData();
		// 处理attributionPlaces
		String attributionPlaceName = "";
		String attributionPlaceId = "";
		for (Map<String, String> hall : hallList) {
			if (ObjectUtil.isNotEmpty(hall)) {
				String label = hall.get("label");
				String businessHallId = hall.get("businessHallId");
				if (ObjectUtil.isNotEmpty(label) && ObjectUtil.isNotEmpty(businessHallId)) {
					attributionPlaceName += label + ",";
					attributionPlaceId += businessHallId + ",";
				}
			}
		}
		//去除最后一个","
		if (attributionPlaceName.length() != 0) {
			attributionPlaceName = attributionPlaceName.substring(0, attributionPlaceName.length() - 1);
		}
		if (attributionPlaceId.length() != 0) {
			attributionPlaceId = attributionPlaceId.substring(0, attributionPlaceId.length() - 1);
		}

		//查询全部营业厅名称    key 为营业厅id  value 为营业厅名称
		SearchParams searchParams1 = new SearchParams();
		List<Map<String, String>> list = businessHallService.getBusinessHall(searchParams1).getData();
//		List<Map<String, String>> list = businessMapper.queryAllHall();
		Map<String, String> allHalls = new HashMap<>();
		for (Map<String, String> stringStringMap : list) {
			if (ObjectUtil.isNotEmpty(stringStringMap)) {
				allHalls.put(stringStringMap.get("businessHallId"), stringStringMap.get("businessHallName"));
			}
		}
		if (params.getUnComplianceType() != null && params.getUnComplianceType().equals(5)) {
			for (BusinessComplianceStatisticsVo vo : voList) {
				IsHallErrorVO sdVo = new IsHallErrorVO();
				sdVo.setDealTime(vo.getDealTime());
				sdVo.setStartTime(vo.getStartTime());
				sdVo.setEndTime(vo.getEndTime());
				sdVo.setBusinessHallId(vo.getBusinessHallId());
				sdVo.setSystemId(vo.getSystemId());
				sdVo.setBusinessCode(vo.getBusinessCode());
				sdVo.setBusinessDetailId(vo.getId());
				//回填系统名称,业务名称,业务不合规类型
				sdVo.setUnComplianceTypeStr(params.getUnComplianceTypeStr());
				sdVo.setSystemName(params.getSystemName());
				sdVo.setBusinessName(params.getBusinessName());
				DecimalFormat df = new DecimalFormat("0.00");
				double dealTime = Double.parseDouble(sdVo.getDealTime());
				double second = 0;
				int minute = 0;
				double ms = 0;
				//转化时间戳
				if (dealTime >= 60000000) {
					second = dealTime / 1000000;
					minute = (int) second / 60;
					second = second - minute * 60;
					sdVo.setDealTime(minute + "分" + df.format(second) + "秒");
				} else if (dealTime >= 1000000) {
					second = dealTime / 1000000;
					sdVo.setDealTime(df.format(second) + "秒");
				} else {
					ms = dealTime / 1000;
					sdVo.setDealTime(df.format(ms) + "毫秒");
				}
				//设置实际营业厅名称和id
				sdVo.setActualPlace(allHalls.get(sdVo.getBusinessHallId()));
				//设置设定营业厅名称和id
				sdVo.setAttributionPlace(attributionPlaceName);
				sdVo.setAttributionPlaceId(attributionPlaceId);
				ihVoList.add(sdVo);
			}
		} else {
			for (BusinessComplianceStatisticsVo sdVo : voList) {
				sdVo.setBusinessDetailId(sdVo.getId());
				//回填系统名称,业务名称,业务不合规类型
				sdVo.setUnComplianceTypeStr(params.getUnComplianceTypeStr());
				sdVo.setSystemName(params.getSystemName());
				sdVo.setBusinessName(params.getBusinessName());
				//回填处理时间(字符串)
				DecimalFormat df = new DecimalFormat("0.00");
				double dealTime = Double.parseDouble(sdVo.getDealTime());
				double second = 0;
				int minute = 0;
				double ms = 0;
				//转化时间戳
				if (dealTime >= 60000000) {
					second = dealTime / 1000000;
					minute = (int) second / 60;
					second = second - minute * 60;
					sdVo.setDealTime(minute + "分" + df.format(second) + "秒");
				} else if (dealTime >= 1000000) {
					second = dealTime / 1000000;
					sdVo.setDealTime(df.format(second) + "秒");
				} else {
					ms = dealTime / 1000;
					sdVo.setDealTime(df.format(ms) + "毫秒");
				}
				sdVoList.add(sdVo);
			}
		}

		return R.ok(new PageDataInfo(page, (params.getUnComplianceType() != null && params.getUnComplianceType() == 5) ? ihVoList : sdVoList));
	}

	/**
	 * 不合规业务详情列表下载
	 *
	 * @param params 查询参数
	 * @return 分页结果集
	 */
	@Override
	public void queryViolationBusinessListExport(BusinessComplianceStatisticsParms params, HttpServletResponse response) throws IOException {
		//取消分页
		params.setPageNum(1);
		params.setPageSize(10000000L);
		List<BusinessComplianceStatisticsVo> businessComplianceStatisticsVos = new ArrayList<>();
		List<IsHallErrorVO> isHallErrorVOS = new ArrayList<>();
		if (params.getUnComplianceType() != null && params.getUnComplianceType().equals(5)) {
			try {
				isHallErrorVOS = (List<IsHallErrorVO>) ((PageDataInfo) queryViolationBusinessList(params).getData()).getData();
			} catch (Exception e) {
				log.error("所选时间表不存在!但表格需要正常导出.");
			}
			//id自增
			int index = 1;
			for (IsHallErrorVO vo : isHallErrorVOS) {
				vo.setNum(index++);
				if (vo.getBusinessHallId() == null || vo.getBusinessHallId().equals("")) {
					vo.setBusinessHallId("-");
				}
				if (vo.getActualPlace() == null || vo.getActualPlace().equals("")) {
					if (vo.getBusinessHallId() == "-") {
						vo.setActualPlace("-");
					} else {
						vo.setActualPlace("未知");
					}
				}
			}
			//excel主标题,如"XX(工号)操作员(姓名)不合规业务_startTime~endTime"
			String title = "不合规业务";
			List<String> titleParams = new ArrayList<>();
			titleParams.add(title);
			titleParams.add(params.getSystemName());
			titleParams.add(params.getBusinessName());
			titleParams.add(params.getOperatorId());
			titleParams.add(params.getOperatorName());
			String formTitleName = ExcelTitleUtils.formTitleName(titleParams, params.getStartTime(), params.getEndTime());
			//列标题
			List<List<String>> headList = new ArrayList<>();
			List<String> titleList = Arrays.asList("序号", "系统名称", "业务名称", "业务不合规类型", "设定归属地ID", "设定归属地", "实际归属地ID", "实际归属地", "操作耗时", "开始时间", "结束时间");
			titleList.forEach(s -> {
				List<String> childHeadList = new ArrayList<>();
				childHeadList.add(formTitleName);
				childHeadList.add(s);
				headList.add(childHeadList);
			});
			ExcelUtil.writeExcel(IsHallErrorVO.class, formTitleName, "不合规业务", isHallErrorVOS, headList, response);
		} else {
			try {
				businessComplianceStatisticsVos = (List<BusinessComplianceStatisticsVo>) ((PageDataInfo) queryViolationBusinessList(params).getData()).getData();
			} catch (Exception e) {
				log.error("所选时间表不存在!但表格需要正常导出.");
			}
			//id自增
			int index = 1;
			for (BusinessComplianceStatisticsVo businessComplianceStatisticsVo : businessComplianceStatisticsVos) {
				businessComplianceStatisticsVo.setNum(index++);
			}
			//excel主标题,如"XX(工号)操作员(姓名)不合规业务_startTime~endTime"
			String title = "不合规业务";
			List<String> titleParams = new ArrayList<>();
			titleParams.add(title);
			if (params.getSystemId() != null) {
				ConfSystem system = systemService.getSystemById(params.getSystemId()).getData();
				if (ObjectUtil.isNotEmpty(system)) {
					titleParams.add(system.getName());
				}
			}
			if (StringUtils.isNotEmpty(params.getBusinessCode())) {
				ConfBusiness confBusiness = new ConfBusiness();
				confBusiness.setBusinessCode(params.getBusinessCode());
				List<ConfBusiness> data = businessService.getBusiness(confBusiness).getData();
				if (ObjectUtil.isNotEmpty(data) && data.size() > 1) {
					confBusiness = data.get(0);
					titleParams.add(confBusiness.getName());
				}
			}
			titleParams.add(params.getOperatorId());
			titleParams.add(params.getOperatorName());
			String formTitleName = ExcelTitleUtils.formTitleName(titleParams, params.getStartTime(), params.getEndTime());
			//列标题
			List<List<String>> headList = new ArrayList<>();
			List<String> titleList = Arrays.asList("序号", "系统名称", "业务名称", "业务不合规类型", "操作耗时", "开始时间", "结束时间");
			titleList.forEach(s -> {
				List<String> childHeadList = new ArrayList<>();
				childHeadList.add(formTitleName);
				childHeadList.add(s);
				headList.add(childHeadList);
			});
			ExcelUtil.writeExcel(BusinessComplianceStatisticsVo.class, formTitleName, "不合规业务", businessComplianceStatisticsVos, headList, response);
		}
	}

	/**
	 * 查询不合规操作员人数
	 */
	@Override
	public List<Long> queryUnComplianceOperatorNumber(BusinessComplianceStatisticsParms params) {
		List<Map<String, Object>> mapList = businessMapper.queryUnComplianceOperatorNumber(params);
		List<Long> list = Arrays.asList(0L, 0L, 0L, 0L, 0L, 0L);
		for (int i = 1; i <= 5; i++) {
			Integer type = null;
			Long number = null;
			for (Map<String, Object> map : mapList) {
				if (ObjectUtil.isNotEmpty(map)) {
					type = (Integer) map.get("un_compliance_type");
					number = (Long) map.get("number");
				}
				if (ObjectUtil.isNotEmpty(type) && type.equals(i)) {
					list.set(i - 1, number);
				}
			}
		}
		return list;
	}

}
